package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.redp.bizimpl.enums.*;
import cc.rengu.redp.bizimpl.igas.domain.PDstChannelInfo;
import cc.rengu.redp.bizimpl.igas.service.PDstChannelInfoService;
import cc.rengu.redp.bizimpl.upmp.common.BusinessContainer;
import cc.rengu.redp.bizimpl.upmp.dao.BTxnLimitCfgMapper;
import cc.rengu.redp.bizimpl.upmp.domain.*;
import cc.rengu.redp.bizimpl.upmp.service.*;
import cc.rengu.redp.bizimpl.upmp.vo.OperationResult;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.Common;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.bizimpl.utils.DateUtils;
import cc.rengu.redp.bizimpl.utils.RedpUpmpUtil;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.DateUtil;
import cc.rengu.redp.common.utils.SortUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 刘玉亮.LL
 */
@Service
@DS("upmp")
public class BTxnLimitCfgServiceImpl extends ServiceImpl<BTxnLimitCfgMapper, BTxnLimitCfg> implements BTxnLimitCfgService {
    @Autowired
    private PDstChannelInfoService pDstChannelInfoService;
    @Autowired
    IUpmpSysParamService upmpSysParamService;
    @Autowired
    private IUpmpPrivilegeCheckService authPrivilegeCheckService;
    @Autowired
    private IBizTmpService bizTmpService;
    @Autowired
    private IBizHisService bizHisService;
    @Autowired
    private IUpmpBMchntBaseInfoService mchntBaseInfoService;
    @Autowired
    private IUpmpBMchntLevelInfoService mchntLevelInfoService;
    @Autowired
    private  BTxnLimitCfgService bTxnLimitCfgService;

    //导出
    @Override
    public IPage<BTxnLimitCfg> findBTxnLimitCfgExcel(QueryRequest request, BTxnLimitCfg bTxnLimitCfg) {
        try {
            Page<BTxnLimitCfg> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            IPage<BTxnLimitCfg> pageOrgCharge =this.findByPage(request, bTxnLimitCfg);
            return pageOrgCharge;
        } catch (Exception e) {
            log.error("获取角色信息失败", e);
            return null;
        }
    }

    @Override
    public BTxnLimitCfg findByUniqueIndex(String instId, String limitType, String limitInst, String limitAcctType){
        QueryWrapper<BTxnLimitCfg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("inst_id",instId);
        queryWrapper.eq("limit_type",limitType);
        queryWrapper.eq("limit_inst",limitInst);
        queryWrapper.eq("limit_acct_type",limitAcctType);
        return this.getOne(queryWrapper);
    }
    @Override
    public IPage<BTxnLimitCfg> findByPage(QueryRequest request, BTxnLimitCfg info){
        //TODO 查询逻辑有问题，待完善
        try {
            String instId = "";
            //获取当前用户的法人id
            UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);

            boolean flag = user.isAdmin();
            if (flag) {
                instId = info.getInstId();
            }
            if (!(flag) || StringUtils.isBlank(instId)) {
                instId = user.getInstId();
            }
            if (StringUtils.isBlank(instId)) {
                throw new RedpException("多法人机构号为空");
            }

            LambdaQueryWrapper<BTxnLimitCfg> queryWrapper = new LambdaQueryWrapper<>();
            if (StringUtils.isNotBlank(info.getInstId())) {
                queryWrapper.eq(BTxnLimitCfg::getInstId, instId);
            }

            String mchntNo = info.getMchntNo();
            if (StringUtils.isNotBlank(mchntNo)) {
                queryWrapper.eq(BTxnLimitCfg::getLimitInst, mchntNo);
            }

            Page<BTxnLimitCfg> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            Page<BTxnLimitCfg> cfgPage = this.page(page, queryWrapper);
            for (BTxnLimitCfg record : cfgPage.getRecords()) {
                record.setMchntNo(record.getLimitInst());
                UpmpBMchntBaseInfo byMchntNo = mchntBaseInfoService.findByMchntNo(record.getLimitInst());
                if (Common.isNotBlank(byMchntNo)) {
                    record.setMchntName(byMchntNo.getMchntName());
                    record.setMchntType(byMchntNo.getMchntType());
                }

            }
            return cfgPage;
        } catch (Exception e) {
            log.error("查询失败", e);
            return null;
        }
    }

    /**
     * 根据通道信息查询支持的限额列表
     * @param instId
     * @param limitType
     * @param limitInst
     * @return
     */
    @Override
    public List<BTxnLimitCfg> findByPDstChannelInfo(String instId, String limitType, String limitInst){
        LambdaQueryWrapper<BTxnLimitCfg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BTxnLimitCfg::getInstId,instId);
        queryWrapper.eq(BTxnLimitCfg::getLimitType,limitType);
        queryWrapper.eq(BTxnLimitCfg::getLimitInst,limitInst);
        List<BTxnLimitCfg> list =  this.list(queryWrapper);
        return list;
    }

    @Override
    public OperationResult saveData(BTxnLimitCfg entity, HttpServletRequest request)throws RedpException{
        String dstChannelId = request.getParameter("dstChannelId");
//        String channelTxn = request.getParameter("channelTxn");
        java.util.Map<String, Object> result = com.google.common.collect.Maps.newHashMap();
        if (!PageOptFlagEnum.OPT_FLAG_VIEW.getType().equals(entity.getOptFlag())) {
            if (LimitParamTypeEnum.LIMIT_CHNL_TXN.getType().equals(entity.getLimitType())) {//通道限额
                PDstChannelInfo pDstChannelInfo = pDstChannelInfoService.findOne(entity.getInstId(), dstChannelId);
                if (Common.isNotBlank(pDstChannelInfo)) {
                    String code = "";
                    if (PageOptFlagEnum.OPT_FLAG_ADD.getType().equals(entity.getOptFlag())) {
                        code = pDstChannelInfoService.getOprMenuName() + PageOptFlagEnum.OPT_FLAG_ADD.getDesc();
                    } else if (PageOptFlagEnum.OPT_FLAG_UPDATE.getType().equals(entity.getOptFlag())) {
                        code = pDstChannelInfoService.getOprMenuName() + PageOptFlagEnum.OPT_FLAG_UPDATE.getDesc();
                    } else if (PageOptFlagEnum.OPT_FLAG_USE.getType().equals(entity.getOptFlag())) {
                        code = pDstChannelInfoService.getOprMenuName() + PageOptFlagEnum.OPT_FLAG_USE.getDesc();
                    } else if (PageOptFlagEnum.OPT_FLAG_STOP.getType().equals(entity.getOptFlag())) {
                        code = pDstChannelInfoService.getOprMenuName() + PageOptFlagEnum.OPT_FLAG_STOP.getDesc();
                    } else if (PageOptFlagEnum.OPT_FLAG_CANCEL.getType().equals(entity.getOptFlag())) {
                        code = pDstChannelInfoService.getOprMenuName() + PageOptFlagEnum.OPT_FLAG_CANCEL.getDesc();
                    } else {
//                          code=pDstChannelInfoService.getChkMenuName()+PageOptFlagEnum.OPT_FLAG_CHECK.getDesc();
                        log.error("支付通道管理不支持审核操作");
                        throw new RedpException("支付通道管理不支持审核操作");
                    }
                    this.saveDataFromChnl(entity, code);
                }
            } else {
                    QueryWrapper<BTxnLimitCfg> queryWrapper=new QueryWrapper<>();
                    queryWrapper.eq("inst_id", entity.getInstId());
                    queryWrapper.eq("limit_type", entity.getLimitType());
                    queryWrapper.eq("limit_inst", entity.getLimitInst());
                    bTxnLimitCfgService.saveOrUpdate(entity, queryWrapper);
            }
        }
        return OperationResult.buildSuccessResult("数据保存处理完成", result);
    }

    @Override
    public OperationResult getMchntLevel(String instId, String mchntNo) {
        //TODO
        UpmpBMchntBaseInfo byMchntNo = mchntBaseInfoService.findByMchntNo(mchntNo);

//        List<TxnLimitCfgVo> txnLimitCfgVos = null;
        if(Common.isBlank(byMchntNo)){
            return OperationResult.buildFailureResult("获取商户信息失败");
        }
        @NotBlank(message = "{required}")
        String mchntLevel = byMchntNo.getMchntLevel();
        UpmpBMchntLevelInfo bMchntLevelInfo = mchntLevelInfoService.findOneByCode(mchntLevel, "01", instId);
//        if (Common.isNotBlank(bMchntLevelInfo)){
//            txnLimitCfgVos = merchantGradeQuotalManagerService.queryBankGradeQuota(instId, mchntlevelinfo.getMchntLevelCode());
//        }
        return null;

    }

    /**
     * 保存支付通道的限额，如果需要审核时不执行审核操作，临时表、正式表、历史表都插入数据且状态为审核通过；不需要审核时则
     * @param bTxnLimitCfg
     */
    public void saveDataFromChnl(BTxnLimitCfg bTxnLimitCfg,String code) throws RedpException {
        UpmpUserInfoVO user = RedpUpmpUtil.getCurrentUser(bTxnLimitCfg.getInstId());
        String lastUpddt = DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
        UpmpPrivilegeCheck privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(bTxnLimitCfg.getInstId(), code);
        List<BTxnLimitCfg> newCfgList=new ArrayList<>();//本次保存入库的数据集合，后面跟数据库中的数据集合比较，删除数据库中多余的数据
        String bizOpr=bizTmpService.convertOptFlagToBizOpr(bTxnLimitCfg.getOptFlag());
        if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {//需要审核
            BTxnLimitCfg cfg = this.findByUniqueIndex(bTxnLimitCfg.getInstId(), bTxnLimitCfg.getLimitType(), bTxnLimitCfg.getLimitInst(),SettleAccTypeEnum.ALL_ACCOUNT.getType());
            String realId="";
            if (Common.isNotBlank(cfg)) {//修改时从数据库取realId
                realId = cfg.getId();
            }else{
                cfg = new BTxnLimitCfg();
            }
            BeanUtils.copyProperties(bTxnLimitCfg, cfg);
            if(StringUtils.isEmpty(realId)){
                cfg.setId(null);
            }else{
                cfg.setId(realId);
            }
            cfg.setLimitAcctType(SettleAccTypeEnum.ALL_ACCOUNT.getType());
            cfg.setLastOprId(user.getUserName());
            cfg.setLastUpdateTime(lastUpddt);
            cfg.setLastAuditId(user.getUserName());
            cfg.setLastAuditTime(lastUpddt);
            cfg.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());
            cfg.setStatus(IgasYesOrNoEnum.Yes.getType());
            this.save(cfg);
            if (Common.isBlank(realId)) {//新增后取realId
                realId = cfg.getId();
            }
            //保存到临时表
            bizTmpService.saveBizTmp(cfg, user, user.getInstId(), bizOpr, DateUtil.getDateFormat(new Date(), DateUtil.FULL_TIME_WITH_MILL_SPLIT_PATTERN)
                    , String.valueOf(pDstChannelInfoService.getOprMenuId()), pDstChannelInfoService.getOprMenuName(), cfg.getStatus()
                    , cfg.getAuditStatus(), realId, "",null,null,null);
            //保存到历史表
            bizHisService.saveBizHisNew(cfg,cfg,user,user.getInstId(),bizOpr,lastUpddt, String.valueOf(pDstChannelInfoService.getOprMenuId()), pDstChannelInfoService.getOprMenuName(),realId,null,null,null);
            newCfgList.add(cfg);
        }else{//不需要审核
            QueryWrapper<BTxnLimitCfg> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("inst_id", bTxnLimitCfg.getInstId());
            queryWrapper.eq("limit_type", bTxnLimitCfg.getLimitType());
            queryWrapper.eq("limit_inst", bTxnLimitCfg.getLimitInst());
            queryWrapper.eq("limit_Acct_Type",SettleAccTypeEnum.ALL_ACCOUNT.getType());
            List<BTxnLimitCfg> list = bTxnLimitCfgService.list(queryWrapper);
            BTxnLimitCfg cfg = this.findByUniqueIndex(bTxnLimitCfg.getInstId(), bTxnLimitCfg.getLimitType(), bTxnLimitCfg.getLimitInst(), SettleAccTypeEnum.ALL_ACCOUNT.getType());
            String realId="";
            if (Common.isNotBlank(cfg)) {//修改时从数据库取realId
                realId = cfg.getId();
            }else{
                cfg = new BTxnLimitCfg();
            }
            BeanUtils.copyProperties(bTxnLimitCfg, cfg);
            if(StringUtils.isEmpty(realId)){
                cfg.setId(null);
            }else{
                cfg.setId(realId);
            }
            cfg.setLimitAcctType(SettleAccTypeEnum.ALL_ACCOUNT.getType());
            cfg.setLastOprId(user.getOprId());
            cfg.setLastUpdateTime(lastUpddt);
            cfg.setLastAuditId(user.getOprId());
            cfg.setLastAuditTime(lastUpddt);
            cfg.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());
            cfg.setStatus(IgasYesOrNoEnum.Yes.getType());

            if (StringUtils.isNotBlank(bTxnLimitCfg.getId())&&bTxnLimitCfg.getId().equals(cfg.getId())){
                QueryWrapper queryWrapper1=new QueryWrapper();
                queryWrapper1.eq("id",bTxnLimitCfg.getId());
                this.update(cfg,queryWrapper1);
            }else {
                cfg.setId(CommonUtils.getUUID());
                cfg.setOprId(user.getOprId());
                this.save(cfg);
            }
            if (Common.isBlank(realId)) {//新增后取realId
                realId = cfg.getId();
            }
            //保存到历史表
            bizHisService.saveBizHisNew(cfg,cfg,user,user.getInstId(),bizOpr,lastUpddt, String.valueOf(pDstChannelInfoService.getOprMenuId()), pDstChannelInfoService.getOprMenuName(),realId,null,null,null);
            newCfgList.add(cfg);
        }
        //检查是否有删除的数据
        List<BTxnLimitCfg> orgList = this.findByPDstChannelInfo(bTxnLimitCfg.getInstId(),bTxnLimitCfg.getLimitType(),bTxnLimitCfg.getLimitInst());
        List<String> delList= Lists.newArrayList();//待删除正式表数据集合
        List<BizTmp> delTmpList= Lists.newArrayList();//待删除临时表数据集合
        for(BTxnLimitCfg orgcfg : orgList){
            boolean match=false;
            for(BTxnLimitCfg cfg:newCfgList){
                if(cfg.getId().equals(orgcfg.getId())){
                    match=true;
                }
            }
            if(!match){//在新的数据列表中没有找到
                delList.add(orgcfg.getId());
                //保存进历史表
                bizHisService.saveBizHisNew(orgcfg,orgcfg,user,user.getInstId(),bizOpr,lastUpddt, String.valueOf(pDstChannelInfoService.getOprMenuId()), pDstChannelInfoService.getOprMenuName(),orgcfg.getId(),null,null,null);
                BizTmp tmp = bizTmpService.getById(orgcfg.getId());//
                if(Common.isNotBlank(tmp)){
                    delTmpList.add(tmp);
                }
            }
        }
        if(delList.size()>0){//删除正式表多余数据
            this.baseMapper.deleteBatchIds(delList);
        }
        if(delTmpList.size()>0){//删除临时表多余数据
            bizTmpService.delete(delTmpList);
        }
    }

    @Transactional(value = "transactionManager")
    public void stopMcGradeQuota(HttpServletRequest request,BTxnLimitCfg req) throws RedpException {
//        TxnLimitCfgVo txnCfginfo = getMcGradeQuotaDetail(req);
        UpmpUserInfoVO user = RedpUpmpUtil.getCurrentUser(req.getInstId());
        //        Organization org = organizationService.getOrgByCode(user.getOrgCode(), user.getInstId());

        UpmpPrivilegeCheck privilegeCheckByPrivilegeCode = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(req.getInstId(), "商户等级限额管理:停用");
        if (null == privilegeCheckByPrivilegeCode) {
            throw new RedpException("获取审核信息失败");
        }
        BTxnLimitCfg oldData = new BTxnLimitCfg();
        BeanUtils.copyProperties(req,oldData);
        boolean checked = BusinessContainer.YES.equals(privilegeCheckByPrivilegeCode.getChecked());

        req.setLastOprId(user.getUserId());
        req.setLastUpdateTime(DateUtils.formatDate(new Date(), DateUtils.DEFAULT_TIME_FORMAT));
        String BizStatus = BizDataStatusEnum.STATUS_DRAFT.getType();
        String AuditStatus = BizDataAuditStatusEnum.AUDIT_STATUS_STOP_CHECKING.getType();

        if(checked){

            req.setBizStatus(BizStatus);
            req.setAuditStatus(AuditStatus);
            //修正式表
//            updateTxnLimitCfgAuthStatus(req);
            bTxnLimitCfgService.saveOrUpdate(req);
            //修改临时表
//            saveBizTmp(req,BizOprEnum.OPR_STOP.getType());
        }else {
            req.setStatus("N");
            req.setBizStatus(BizStatus);
            req.setAuditStatus(AuditStatus);
            //保存正式表
            bTxnLimitCfgService.saveOrUpdate(req);
            //保存历史表
//            saveQuotaBizHis(req,oldData,BizOprEnum.OPR_STOP.getType());
        }
    }

}
